<template>
  <v-touch @panstart="onPanstart" @panmove="onPanmove" @panend="onPanend">
    <div ref="pdfViewer" class="pdf-viewer-wrapper" @click="toggleZoom">
      <div class="viewer-scroller" :style="{'width':totalWidth, 'left':viewerLeft}">
        <PageViewer
          v-for="pageIdx in pageCount"
          :key="pageIdx"
          :pageIndex="pageIdx"
          :pdfDocument="pdfDocument"
          ref="pdfPageViewers"
          class="page-viewer"
          :style="{'width':`${pageWidth}px`}"
        ></PageViewer>
      </div>
    </div>
  </v-touch>
</template>

<script>
import PDFJSLib from 'pdfjs-dist'
import PageViewer from './page-viewer'

export default {
  components: {
    PageViewer
  },
  props: {
    url: {
      type: String,
      default: null // 'http://dev.tohouse114.com/CN109286576A.pdf'
    },
    maxZoom: {
      type: Number,
      default: 4
    },
    maxPages: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      pageIndex: 1,
      pdfDocument: null,
      pdfPages: [],
      pageWidth: 0,
      pageHeight: 0,
      totalWidth: '100%',
      viewerLeft: '0px',
      panStart: {
        center: {
          x: 0,
          y: 0
        },
        pos: {
          x: 0,
          y: 0
        },
        pageViewer: null
      }
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.refreshViewer()
    })
  },
  computed: {
    pageCount() {
      var pageNum = this.pdfDocument ? this.pdfDocument.numPages : 0
      if (this.maxPages > 0) {
        return Math.min(this.maxPages, pageNum)
      }
      return pageNum
    }
  },
  methods: {
    async loadPDFFile(fileUrl) {
      if (!fileUrl) {
        return
      }
      plus.nativeUI.showWaiting()
      this.$nextTick(async () => {
        var task = PDFJSLib.getDocument(fileUrl)
        try {
          this.pdfDocument = await task.promise
          this.totalWidth = `${this.pageCount * this.pageWidth}px`
          this.pageIndex = 1
        } catch (ex) {
          debugger
          this.$emit('error', ex)
        }
        plus.nativeUI.closeWaiting()
      })
      return this.pdfDocument
    },
    nextPage() {
      if (this.isZooming()) {
        return true
      }
      var nextPageIndex = this.pageIndex + 1
      this.pageIndex = nextPageIndex <= this.pageCount ? nextPageIndex : this.pageCount
      return nextPageIndex <= this.pageCount
    },
    prePage() {
      if (this.isZooming()) {
        return true
      }
      var prePageIndex = this.pageIndex - 1
      this.pageIndex = prePageIndex > 0 ? prePageIndex : 1
      return prePageIndex > 0
    },
    refreshViewer(url) {
      this.pageWidth = this.$refs.pdfViewer.clientWidth
      this.pageHeight = this.$refs.pdfViewer.clientHeight
      this.pageIndex = 0
      this.pdfDocument = {
        numPages: 0
      }
      url = url || this.url
      if (url) {
        this.loadPDFFile(url)
      }
    },
    isZooming() {
      var pageViewer = this.getPageViewer()
      return pageViewer && pageViewer.zoom > 1
    },
    getPageViewer(index) {
      if (index === null || typeof (index) === 'undefined' || index < 0 || index > this.pageCount) {
        index = this.pageIndex - 1
      }
      return this.$refs.pdfPageViewers[index]
    },
    toggleZoom() {
      var pageViewer = this.getPageViewer()
      if (pageViewer) {
        if (pageViewer.zoom > 1) {
          pageViewer.zoom = 1
        } else {
          pageViewer.zoom = this.maxZoom
        }
      }
    },
    onPanstart(evt) {
      if (!this.isZooming()) {
        return
      }
      var panStart = this.panStart
      var pageViewer = panStart.pageViewer = this.getPageViewer()
      panStart.center.x = evt.center.x
      panStart.center.y = evt.center.y
      panStart.pos.x = pageViewer.posX
      panStart.pos.y = pageViewer.posY
    },
    onPanmove(evt) {
      var panStart = this.panStart
      var pageViewer = panStart.pageViewer
      if (!this.isZooming() || !pageViewer) {
        return
      }
      var maxZoom = this.maxZoom
      var minX = 0 - this.pageWidth * (maxZoom - 1)
      var minY = 0 - this.pageHeight * (maxZoom - 1)
      var deltaX = evt.center.x - panStart.center.x
      var deltaY = evt.center.y - panStart.center.y
      var rect = pageViewer.getCanvas().getBoundingClientRect()
      // console.log(`minY:${minY},rect:${JSON.stringify(rect)}, deltaX:${evt.deltaX}, deltaY:${evt.deltaY}, panStartPos:${panStart.pos.x}, ${panStart.pos.y}, deltaPos:${deltaX}, ${deltaY}}`)
      if (rect.x + deltaX > 0) {
        deltaX = 0 - rect.x
      }
      if (rect.x + deltaX < minX) {
        deltaX = minX - rect.x
      }
      if (rect.y + deltaY > 0) {
        deltaY = 0 - rect.y
      }
      if (rect.y + deltaY < minY) {
        deltaY = minY - rect.y
      }
      pageViewer.posX = panStart.pos.x + (deltaX * 2 / maxZoom)
      pageViewer.posY = panStart.pos.y + (deltaY * 2 / maxZoom)
    },
    onPanend(evt) {
      this.panStart.pageViewer = null
    }
  },
  watch: {
    pageIndex(newVal) {
      if (newVal > 0 && this.pageCount >= 1) {
        this.$nextTick(() => {
          var idx = newVal - 1
          this.viewerLeft = `${0 - idx * this.pageWidth}px`
          var pageViewer = this.getPageViewer(idx)
          pageViewer.show()
        })
      } else {

      }
    },
    url(newVal) {
      this.refreshViewer(newVal)
    }
  }
}
</script>

<style lang="scss" scoped>
.pdf-viewer-wrapper {
  height: 100%;
  position: relative;

  .viewer-scroller {
    overflow: hidden;
    position: absolute;
    height: 100%;
    transition: all ease 300ms;

    .page-viewer {
      height: 100%;
      display: inline-block;
    }
  }
}
</style>
